package com.lin.gameserver.websocket;

import com.lin.gameserver.handler.MessageDispatcher;
import com.lin.gameserver.session.GameSession;
import com.lin.gameserver.session.SessionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import java.nio.ByteBuffer;

/**
 * WebSocket端点，处理WebSocket连接和消息
 */
@ServerEndpoint("/websocket")
public class GameWebSocketEndpoint {
    private static final Logger logger = LoggerFactory.getLogger(GameWebSocketEndpoint.class);
    
    // 会话对象
    private GameSession gameSession;
    
    /**
     * WebSocket连接建立时的处理
     *
     * @param session WebSocket会话
     */
    @OnOpen
    public void onOpen(Session session) {
        // 创建游戏会话
        gameSession = SessionManager.getInstance().createSession(session);
        
        // 设置二进制消息缓冲区大小
        session.setMaxBinaryMessageBufferSize(1024 * 1024); // 1MB
        
        logger.info("WebSocket连接已建立: {}", gameSession.getSessionId());
        MessageLogger.logSessionEvent(gameSession.getSessionId(), "WebSocket连接已建立");
    }
    
    /**
     * 收到二进制消息时的处理
     *
     * @param message 二进制消息
     * @param session WebSocket会话
     */
    @OnMessage
    public void onBinaryMessage(ByteBuffer message, Session session) {
        // 将ByteBuffer转换为byte数组
        byte[] data = new byte[message.remaining()];
        message.get(data);
        
        // 记录收到的消息
        MessageLogger.logReceived(gameSession.getSessionId(), data);
        
        // 更新会话活动时间
        gameSession.updateActiveTime();
        
        // 分发消息到对应的处理器
        MessageDispatcher.getInstance().dispatch(gameSession, data);
    }
    
    /**
     * 收到文本消息时的处理（不处理文本消息，仅记录）
     *
     * @param message 文本消息
     * @param session WebSocket会话
     */
    @OnMessage
    public void onTextMessage(String message, Session session) {
        logger.warn("收到文本消息，但服务器只处理二进制消息。会话: {}, 消息: {}", 
                gameSession.getSessionId(), message);
    }
    
    /**
     * WebSocket连接关闭时的处理
     *
     * @param session WebSocket会话
     * @param reason 关闭原因
     */
    @OnClose
    public void onClose(Session session, CloseReason reason) {
        logger.info("WebSocket连接已关闭: {}, 原因: {}", 
                gameSession.getSessionId(), reason.getReasonPhrase());
        
        MessageLogger.logSessionEvent(gameSession.getSessionId(), 
                "WebSocket连接已关闭: " + reason.getReasonPhrase());
        
        // 移除会话
        SessionManager.getInstance().removeSession(gameSession.getSessionId());
    }
    
    /**
     * WebSocket连接发生错误时的处理
     *
     * @param session WebSocket会话
     * @param error 错误
     */
    @OnError
    public void onError(Session session, Throwable error) {
        logger.error("WebSocket连接发生错误: {}, 错误: {}", 
                gameSession.getSessionId(), error.getMessage(), error);
        
        MessageLogger.logSessionEvent(gameSession.getSessionId(), 
                "WebSocket连接发生错误: " + error.getMessage());
    }
} 